<template>
  <Card class="comment" :bordered="false">
    <template #title> 评论列表 （{{ comment.pagination?.total ?? '-' }}） </template>
    <template #extra>
      <Button type="primary" size="small" target="_blank" :href="getBlogGuestbookUrl()">
        <RocketOutlined />去留言板
      </Button>
    </template>
    <Space class="toolbar">
      <Space>
        <Select
          :loading="loading.state.value"
          class="select"
          :value="filterParams.state"
          @change="handleChange"
        >
          <SelectOption :value="SELECT_ALL_VALUE">全部状态</SelectOption>
          <SelectOption v-for="(state, j) in commentStates" :key="j" :value="state.id">
            <Space>
              <component :is="state.icon"></component>
              {{ state.name }}
            </Space>
          </SelectOption>
        </Select>
        <InputSearch
          :loading="loading.state.value"
          class="search"
          placeholder="输入评论内容、作者信息搜索"
          v-model:value="filterParams.keyword"
          @search="handleSearch"
        />

        <Button type="primary" :loading="loading.state.value" @click="resetParamsAndRefresh">
          <template #icon>
            <ReloadOutlined />
          </template>
          重置并刷新
        </Button>
      </Space>
      <Space>
        <Button :disabled="!selectedIDs.length" type="primary"> <DeleteOutlined />批量删除 </Button>
      </Space>
    </Space>
    <Divider />
    <Spin :spinning="loading.state.value">
      <Table
        :data-source="comment.data"
        rowKey="_id"
        :row-selection="{
          selectedRowKeys: selectedIDs,
          onChange: handleSelect,
        }"
        :pagination="{
          current: comment.pagination?.current_page,
          pageSize: comment.pagination?.per_page,
          total: comment.pagination?.total,
          showSizeChanger: true,
        }"
        @change="handlePaginate"
      >
        <TableColumn key="id" :width="40" title="ID" data-index="id" />
        <TableColumn key="pid" :width="40" title="PID" data-index="pid">
          <template #default="{ record }">{{ record.pid || '-' }}</template>
        </TableColumn>
        <TableColumn key="post_id" :width="40" title="POST_ID" data-index="post_id">
          <template #default="{ record }">
            <Button size="small" type="text" @click="updatePostId(record.post_id)">
              {{ record.post_id || '留言板' }}
            </Button>
          </template>
        </TableColumn>
        <TableColumn key="content" :width="300" title="评论内容" data-index="content">
          <template #default="{ record }">
            <TypographyParagraph
              :ellipsis="{ rows: 6, expandable: true }"
              :content="record.content"
            />
          </template>
        </TableColumn>
        <TableColumn key="author" :width="230" title="个人信息" data-index="author">
          <template #default="{ record }">
            <Space direction="vertical">
              <Space>
                <CommentAvatar :comment="record" />
                <UniversalText :text="record.author.name" />
              </Space>
              <UniversalText placeholder="Left blank" :text="record.author.email" :copyable="true">
                <template #prefix>
                  <MailOutlined />
                </template>
              </UniversalText>
              <Space size="small">
                <LinkOutlined />
                <Placeholder :data="record.author.site" placeholder="Left blank">
                  <TypographyLink target="_blank" rel="noreferrer" :href="record.author.site">
                    点击打开
                  </TypographyLink>
                </Placeholder>
              </Space>
            </Space>
          </template>
        </TableColumn>

        <TableColumn key="agent" :width="230" title="发布于" data-index="agent">
          <template #default="{ record }">
            <Space direction="vertical">
              <UniversalText :text="record.ip" :copyable="true">
                <template #prefix>
                  <GlobalOutlined />
                </template>
              </UniversalText>
              <Space size="small">
                <EnvironmentOutlined />
                <IPLocation :fullname="true" :data="record.ip_location" />
              </Space>
              <Space>
                <CompassOutlined />
                <Popover title="终端信息" placement="right">
                  <template #content>
                    <div>
                      <TypographyParagraph>
                        <UniversalText :text="parseBrowser(record.agent)">
                          <template #prefix> 浏览器 </template>
                        </UniversalText>
                      </TypographyParagraph>
                      <TypographyParagraph>
                        <UniversalText :text="parseOS(record.agent)">
                          <template #prefix> 系统 </template>
                        </UniversalText>
                      </TypographyParagraph>
                      <TypographyParagraph>
                        <UniversalText :text="parseDevice(record.agent)">
                          <template #prefix> 设备 </template>
                        </UniversalText>
                      </TypographyParagraph>
                    </div>
                  </template>
                  {{ parseBrowser(record.agent) }}
                </Popover>
              </Space>
              <UniversalText :text="stringToYMD(record.create_at)">
                <template #prefix> <ClockCircleOutlined /> </template>
              </UniversalText>
            </Space>
          </template>
        </TableColumn>
        <TableColumn key="state" :width="120" title="状态" data-index="state">
          <template #default="{ record }">
            <Space direction="vertical">
              <Tag :color="record.likes > 0 ? 'red' : undefined">
                <template #icon>
                  <LikeOutlined />
                </template>
                {{ record.likes }}个赞
              </Tag>
              <Tag :color="record.dislikes > 0 ? 'gold' : undefined">
                <template #icon>
                  <DislikeOutlined />
                </template>
                {{ record.dislikes }}个踩
              </Tag>
              <Tag :color="cs(record.state).color">
                <template #icon>
                  <component :is="cs(record.state).icon" />
                </template>
                {{ cs(record.state).name }}
              </Tag>
              <Tag>
                <template #icon>
                  <LineHeightOutlined />
                </template>
                {{ record.content.length }}字
              </Tag>
            </Space>
          </template>
        </TableColumn>
        <TableColumn key="action" :width="110" title="操作" data-index="action">
          <template #default="{ record, index }">
            <Space direction="vertical">
              <Button size="small" type="text" :block="true" @click="editData(index)">
                <EditOutlined />评论详情
              </Button>
              <template v-if="record.state === CommentState.Auditing">
                <Button
                  size="small"
                  type="text"
                  :block="true"
                  @click="handleStateChange([record], CommentState.Published)"
                >
                  <CheckOutlined />
                  <TypographyText type="success">审核通过</TypographyText>
                </Button>
              </template>
              <template v-else-if="record.state === CommentState.Published">
                <Button
                  size="small"
                  type="text"
                  :block="true"
                  :danger="true"
                  @click="handleStateChange([record], CommentState.Spam)"
                >
                  <StopOutlined />
                  标为垃圾
                </Button>
              </template>
              <template
                v-if="
                  record.state === CommentState.Auditing || record.state === CommentState.Published
                "
              >
                <Button
                  size="small"
                  type="text"
                  :block="true"
                  :danger="true"
                  @click="handleStateChange([record], CommentState.Deleted)"
                >
                  <DeleteOutlined />
                  移回收站
                </Button>
              </template>
              <template
                v-if="record.state === CommentState.Deleted || record.state === CommentState.Spam"
              >
                <Button
                  size="small"
                  type="text"
                  :block="true"
                  @click="handleStateChange([record], CommentState.Auditing)"
                >
                  <EditOutlined />
                  <TypographyText type="warning">退为草稿</TypographyText>
                </Button>
                <Button
                  size="small"
                  type="text"
                  :block="true"
                  :danger="true"
                  @click="handleDelete([record])"
                >
                  <DeleteOutlined />
                  彻底删除
                </Button>
              </template>
              <Button
                size="small"
                type="link"
                target="_blank"
                :href="getBlogURLByPostID(record.post_id)"
              >
                <LinkOutlined />宿主页面
              </Button>
            </Space>
          </template>
        </TableColumn>
      </Table>
    </Spin>
    <EditDrawer
      :visible="isVisibleModal"
      :loading="submitting.state.value"
      :comment="activeEditData"
      :on-cancel="closeModal"
      :on-submit="handleSubmit"
    />
  </Card>
</template>

<script lang="ts" setup>
import { ref, reactive, toRaw, watch, onMounted, computed } from 'vue'
import {
  RocketOutlined,
  ReloadOutlined,
  CheckOutlined,
  StopOutlined,
  EditOutlined,
  DeleteOutlined,
  MailOutlined,
  LinkOutlined,
  GlobalOutlined,
  EnvironmentOutlined,
  CompassOutlined,
  ClockCircleOutlined,
  LikeOutlined,
  DislikeOutlined,
  LineHeightOutlined,
} from '@ant-design/icons-vue'
import { useRoute } from 'vue-router'
import _ from 'lodash'
import {
  Button,
  Card,
  Divider,
  InputSearch,
  Modal,
  Popover,
  Select,
  SelectOption,
  Space,
  Spin,
  Table,
  TableColumn,
  TablePaginationConfig,
  Tag,
  TypographyLink,
  TypographyParagraph,
  TypographyText,
} from 'ant-design-vue'
import Placeholder from '@/components/Placeholder/index.vue'
import { useLoading } from '@/handcer'
import CommentAvatar from './Avatar.vue'
import UniversalText from '@/components/UniversalText/index.vue'
import IPLocation from '@/components/IPLocation/index.vue'
import {
  Comment as CommentType,
  CommentState,
  cs,
  commentStates,
  // COMMENT_GUESTBOOK_POST_ID,
} from '@/constants/comment'
import type { ResponsePaginationData } from '@/constants/request'
import { SortType } from '@/constants/sort'
import { stringToYMD } from '@/transformers/date'
import { getBlogGuestbookUrl, getBlogURLByPostID } from '@/transformers/url'
import { getComments, deleteComments, putComment, updateCommentsState } from '@/store/comment'
import type { GetCommentsParams } from '@/store/comment'
import { parseBrowser, parseOS, parseDevice } from '@/transformers/ua'
import EditDrawer from './EditDrawer.vue'

const loading = useLoading()
const submitting = useLoading()

const route = useRoute()
const { post_id } = route.query
const postIdParam = post_id ? Number(post_id) : undefined

const LIST_ALL_VALUE = 'ALL'
const SELECT_ALL_VALUE = 'ALL'
const DEFAULT_FILTER_PARAMS = Object.freeze({
  postId: LIST_ALL_VALUE as number | typeof LIST_ALL_VALUE,
  state: SELECT_ALL_VALUE as typeof SELECT_ALL_VALUE | CommentState,
  sort: SortType.Desc,
})

// 列表数据
const comment = reactive<ResponsePaginationData<CommentType>>({
  data: [],
  pagination: undefined,
})

// 过滤参数
const serarchKeyword = ref('')
const filterParams = reactive({
  keyword: '',
  ...DEFAULT_FILTER_PARAMS,
  postId: postIdParam || DEFAULT_FILTER_PARAMS.postId,
})
const updatePostId = (postId: number | string) => {
  filterParams.postId = Number(postId)
}

// 多选
const selectedIDs = ref<Array<string>>([])
// const selectComments = computed(() => {
//   comment.data.filter((c) => selectedIDs.value.includes(c._id!));
// });
const handleSelect = (ids: any[]) => {
  selectedIDs.value = ids
}

// 弹窗
const activeEditDataIndex = ref<number | null>(null)
const isVisibleModal = ref<boolean>(false)
const activeEditData = computed(() => {
  const index = activeEditDataIndex.value
  return index !== null ? comment.data[index] : null
})

const closeModal = () => {
  isVisibleModal.value = false
}
const editData = (index: number) => {
  activeEditDataIndex.value = index
  isVisibleModal.value = true
}

const handleSearch = () => {
  fetchData()
}

const fetchData = (params?: GetCommentsParams) => {
  const getParams = {
    ...params,
    sort: filterParams.sort,
    post_id: filterParams.postId !== LIST_ALL_VALUE ? filterParams.postId : undefined,
    state: filterParams.state !== SELECT_ALL_VALUE ? filterParams.state : undefined,
    keyword: serarchKeyword.value ? serarchKeyword.value : undefined,
  }
  loading.promise(getComments(getParams)).then((response) => {
    comment.data = response.data
    comment.pagination = response.pagination
  })
}

const resetParamsAndRefresh = () => {
  serarchKeyword.value = ''
  if (_.isEqual(toRaw(filterParams), DEFAULT_FILTER_PARAMS)) {
    fetchData()
  } else {
    filterParams.state = DEFAULT_FILTER_PARAMS.state
    filterParams.sort = DEFAULT_FILTER_PARAMS.sort
    filterParams.postId = DEFAULT_FILTER_PARAMS.postId
  }
  fetchData()
}

// 重新刷新数据
const refreshData = () => {
  fetchData({
    page: comment.pagination?.current_page,
    per_page: comment.pagination?.per_page,
  })
}

// 翻页

// pagination, filters, sorter, { currentDataSource };
const handlePaginate = (pagination: TablePaginationConfig) => {
  const { current, pageSize } = pagination
  fetchData({ page: current, per_page: pageSize })
}

const handleChange = (value: any) => {
  filterParams.state = value
}

// 单个删除
const handleDelete = (comments: Array<CommentType>) => {
  Modal.confirm({
    title: `确定要彻底删除 ${comments.length} 个评论吗？`,
    content: '该行为是物理删除，不可恢复！',
    centered: true,
    onOk: () => {
      deleteComments(
        comments.map((c) => c._id!),
        _.uniq(comments.map((c) => c.post_id))
      ).then(() => {
        refreshData()
      })
    },
  })
}

const handleStateChange = (comments: Array<CommentType>, state: CommentState) => {
  Modal.confirm({
    title: `确定要将 ${comments.length} 个评论更新为「 ${cs(state).name} 」状态吗？`,
    content: '操作不可撤销',
    centered: true,
    onOk: () =>
      updateCommentsState(
        comments.map((c) => c._id!),
        _.uniq(comments.map((c) => c.post_id)),
        state
      ).then(() => {
        refreshData()
      }),
  })
}

// 提交表单
const handleSubmit = (comment: CommentType) => {
  putComment({
    ...activeEditData.value,
    ...comment,
  }).then(() => {
    closeModal()
    refreshData()
  })
}

// 监听过滤参数重刷数据
watch(
  () => filterParams,
  () => fetchData()
)

onMounted(() => {
  fetchData()
})
</script>

<style lang="less" scoped>
.comment {
  .toolbar {
    display: flex;
    justify-content: space-between;

    .select {
      width: 130px;
    }
    .search {
      width: 200px;
    }
  }
}
</style>
